package com.leyou.search.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.leyou.common.utils.JsonUtils;
import com.leyou.item.bo.SpuBo;
import com.leyou.item.pojo.Sku;
import com.leyou.item.pojo.SpecParam;
import com.leyou.item.pojo.Spu;
import com.leyou.item.pojo.SpuDetail;
import com.leyou.search.clients.CategoryClient;
import com.leyou.search.clients.GoodsClient;
import com.leyou.search.clients.SpecClient;
import com.leyou.search.pojo.Goods;
import com.leyou.search.repository.GoodsRepository;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Author: taft
 * @Date: 2018-12-24 11:42
 */
@Service
public class IndexService {

    @Autowired
    private CategoryClient categoryClient;

    @Autowired
    private GoodsClient goodsClient;

    @Autowired
    private SpecClient specClient;

    @Autowired
    private GoodsRepository goodsRepository;

    //把spu转换为Goods对象
    public Goods buildGoods(SpuBo spuBo) {

        Goods goods = new Goods();
        //把其他相同的属性对应赋值
        BeanUtils.copyProperties(spuBo, goods);


        //处理goods独有的属性

        // 所有需要被搜索的信息，包含标题，分类，甚至品牌

        //拿到了分类的id，把分类的id处理成分类的名称

        List<String> names = categoryClient.queryNameByIds(Arrays.asList(spuBo.getCid1(), spuBo.getCid2(), spuBo.getCid3()));

        //把all值生成并赋值给all属性
        goods.setAll(spuBo.getTitle() + " " + StringUtils.join(names, " "));

        //TODO 根据spu查询所有的sku
        List<Sku> skus = this.goodsClient.querySkuBySpuId(spuBo.getId());


        List<Long> price = new ArrayList<>();


        //用来存放所有的要被存入goods对象中的sku
        List<Map<String, Object>> skuList = new ArrayList<>();

        skus.forEach(sku -> {
            //取出每个sku的价格封装到price集合中
            price.add(sku.getPrice());
            Map<String, Object> skuInfo = new HashMap<>();
            skuInfo.put("id", sku.getId());
            skuInfo.put("title", sku.getTitle());
            skuInfo.put("price", sku.getPrice());
            skuInfo.put("image", sku.getImages());

            skuList.add(skuInfo);
        });

        //所有的sku的价格集合
        goods.setPrice(price);

        //当前spu对应的sku
        goods.setSkus(JsonUtils.serialize(skuList));

        // 可搜索的规格参数，key是参数名，值是参数值
        Map<String, Object> specs = new HashMap<>();

        //查询出所有的可搜索规格参数
        List<SpecParam> specParams = this.specClient.querySpecParam(null, spuBo.getCid3(), true, null);

        //获取到spu的通用规格参数，以及特有规格参数
        SpuDetail spuDetail = this.goodsClient.querySpuDetailById(spuBo.getId());

        //获取到所有的通用规格参数，并把其转换为一个Map对象
        Map<Long,Object> genericSpec = JsonUtils.parseMap(spuDetail.getGenericSpec(),Long.class,Object.class);

        //获取特有的规格参数，并转为map
        Map<Long,List<String>> specialSpec = JsonUtils.nativeRead(spuDetail.getSpecialSpec(), new TypeReference<Map<Long, List<String>>>() {
        });


        //迭代可搜索规格参数，用来封装可搜索map
        specParams.forEach(specParam -> {
            //map的key就是参数的名称
            String key = specParam.getName();

            //参数的id
            Long id = specParam.getId();

            //参数的值
            Object value = null;
            //判断属性是特有规格属性还是通用属性
            if (specParam.getGeneric()){

                //通用参数
                value = genericSpec.get(id);

                //为了避免空指针异常
                if (null==value){
                    value = "";
                }

                if (specParam.getNumeric()){
                    //数值类型需要加分段
                    value = this.chooseSegment(value.toString(),specParam);
                }
            }else{
                value = specialSpec.get(id);
            }



            specs.put(key,value);
        });



        goods.setSpecs(specs);


        return goods;

    }

    private String chooseSegment(String value, SpecParam p) {
        double val = NumberUtils.toDouble(value);
        String result = "其它";
        // 保存数值段
        for (String segment : p.getSegments().split(",")) {
            String[] segs = segment.split("-");
            // 获取数值范围
            double begin = NumberUtils.toDouble(segs[0]);
            double end = Double.MAX_VALUE;
            if(segs.length == 2){
                end = NumberUtils.toDouble(segs[1]);
            }
            // 判断是否在范围内
            if(val >= begin && val < end){
                if(segs.length == 1){
                    result = segs[0] + p.getUnit() + "以上";
                }else if(begin == 0){
                    result = segs[1] + p.getUnit() + "以下";
                }else{
                    result = segment + p.getUnit();
                }
                break;
            }
        }
        return result;
    }

    public void createIndex(Long id) {

        Spu spu = this.goodsClient.querySpuById(id);
        SpuBo spuBo = new SpuBo();

        BeanUtils.copyProperties(spu,spuBo);

        Goods goods = this.buildGoods(spuBo);

        this.goodsRepository.save(goods);

    }

    public void deleteIndex(Long id) {

    }
}
